package leetcode.helper;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import leetcode.helper.tree.ListNode;
import leetcode.helper.tree.Node;
import leetcode.helper.tree.TreeArray;
import leetcode.helper.tree.TreeNode;

public class HelpDebug {
	public static void printInputs(String expect, Object... inputDatas) {
		printDataExpectObject(expect, inputDatas);
	}

	public static void printInputs(int[][] expect, Object... inputDatas) {
		printDataExpectObject(expect, inputDatas);
	}

	public static void printInputs(int expect, Object... inputDatas) {
		printDataExpectObject(expect, inputDatas);
	}

	public static void printInputs(int expect, int[][] inputDatas) {
		printDataExpectObject(expect, inputDatas);
	}

	public static void printInputs(int expect, char[] inputDatas) {
		printDataExpectObject(expect, inputDatas);
	}

	public static void printInputs(int[] expect, Object... inputDatas) {
		printDataExpectObject(expect, inputDatas);
	}

	public static void printInputs(String[] expect, Object... inputDatas) {
		printDataExpectObject(expect, inputDatas);
	}

	public static void printInputs(TreeNode input1, TreeNode input2, TreeNode expect) {
		print(input1);
		print(input2);
		print(expect);
	}

	public static void printDataExpectObject(Object expect, Object... inputDatas) {
		System.out.println("===============================================");
		System.out.println("输入数据：");
		printObjects(inputDatas);
		System.out.println("期望结果：");
		print(expect);
		System.out.println("我的结果：");
	}

	public static void printArray2(int[][] array) {
		if (array == null)
			return;
		System.out.println("[");
		for (int[] element : array) {
			for (int element2 : element) {
				System.out.print(element2 + ",");
			}
			System.out.println("");
		}
		System.out.print("]");
	}

	public static void printArray2(String[][] array) {
		if (array == null)
			return;
		System.out.println("[");
		for (String[] element : array) {
			for (String element2 : element) {
				System.out.print(element2 + ",");
			}
			System.out.println("");
		}
		System.out.print("]");
	}

	public static void printArray2long(long[][] array) {
		if (array == null)
			return;
		System.out.println("[");
		for (long[] element : array) {
			for (long element2 : element) {
				System.out.print(element2 + ",");
			}
			System.out.println("");
		}
		System.out.print("]");
	}

	public static void printArray2(Integer[][] array) {
		if (array == null)
			return;
		System.out.println("[");
		for (Integer[] element : array) {
			for (Integer element2 : element) {
				System.out.print(element2 + ",");
			}
			System.out.println("");
		}
		System.out.print("]");
	}

	public static void printArray(int[] array) {
		if (array == null)
			return;
		System.out.print("[");
		for (int element : array) {
			System.out.print(element + ",");
		}
		System.out.print("]");
		System.out.println("");
	}

	public static void printArray(long[] array) {
		if (array == null)
			return;
		System.out.print("[");
		for (long element : array) {
			System.out.print(element + ",");
		}
		System.out.print("]");
		System.out.println("");
	}

	public static void printArray(char[] array) {
		if (array == null)
			return;
		System.out.print("[");
		for (char element : array) {
			System.out.print(element + ",");
		}
		System.out.print("]");
		System.out.println("");
	}

	public static void printArray(Integer[] array) {
		if (array == null)
			return;
		System.out.print("[");
		for (Integer element : array) {
			System.out.print(element + ",");
		}
		System.out.print("]");
		System.out.println("");
	}

	public static void printArray(String[] array) {
		if (array == null)
			return;
		System.out.print("[");
		for (String element : array) {
			System.out.print(element + ",");
		}
		System.out.print("]");
		System.out.println("");
	}

	public static void printObjects(Object... datas) {
		for (Object o : datas) {
			print(o);
			System.out.println("---");
		}
	}

	public static void print(Object o) {
		if (o == null) {
			System.out.println("object is null");
			return;
		}
		if (o instanceof Integer[][]) {
			printArray2((Integer[][]) o);
			return;
		}
		if (o instanceof String[][]) {
			printArray2((String[][]) o);
			return;
		}
		if (o instanceof int[][]) {
			printArray2((int[][]) o);
			return;
		}
		if (o instanceof long[][]) {
			printArray2long((long[][]) o);
			return;
		}
		if (o instanceof int[]) {
			printArray((int[]) o);
			return;
		}
		if (o instanceof long[]) {
			printArray((long[]) o);
			return;
		}
		if (o instanceof char[]) {
			printArray((char[]) o);
			return;
		}
		if (o instanceof Integer[]) {
			printArray((Integer[]) o);
			return;
		}
		if (o instanceof String[]) {
			printArray((String[]) o);
			return;
		}
		if (o instanceof TreeNode) {
			printTreeNode((TreeNode) o);
			return;
		}
		if (o instanceof char[][]) {
			printArray3((char[][]) o);
			return;
		}

		if (o instanceof boolean[][]) {
			printArray4((boolean[][]) o);
			return;
		}
		if (o instanceof Boolean[][]) {
			printArray41((Boolean[][]) o);
			return;
		}
		if (o instanceof boolean[]) {
			printArray4((boolean[]) o);
			return;
		}
		if (o instanceof ListNode[]) {
			ListNode.prinArray((ListNode[]) o);
			return;
		}
		if (o instanceof ArrayList<?>) {
			System.out.println("[");
			for (Object ino : (ArrayList<?>) o) {
				if (ino instanceof ArrayList<?>) {
					for (Object ino2 : (ArrayList<?>) ino) {
						System.out.print(ino2 + ",");
					}
				} else {
					System.out.print(ino + ",");
				}
			}
			System.out.println(" ");
			System.out.println("]");
			return;
		}

		if (o instanceof Node) {
			printArray(node2array((Node) o));
			return;
		}

		if (o instanceof ListNode) {
			System.out.print("[");
			new ListNode().printListNode((ListNode) o);
			System.out.print("]");
			System.out.println("");
			return;
		}
		if (o != null) {
			System.out.print("[");
			System.out.print(o.toString());
			System.out.print("]");
			System.out.println("");
		}
	}

	private static void printArray4(boolean[] o) {
		System.out.println("[");
		for (boolean b : o) {
			System.out.print(b + ",");
		}
		System.out.print("]");

	}

	private static void printArray41(Boolean[][] o) {
		System.out.println("[");
		for (Boolean[] bb : o) {
			for (Boolean b : bb) {
				System.out.print(b + ",");
			}
			System.out.println("");
		}
		System.out.print("]");

	}

	public static void printArray3(char[][] array) {
		if (array == null)
			return;
		System.out.println("[");
		for (char[] element : array) {
			for (char element2 : element) {
				System.out.print(element2 + ",");
			}
			System.out.println("");
		}
		System.out.print("]");
	}

	public static void printArray4(boolean[][] array) {
		if (array == null)
			return;
		System.out.println("[");
		for (boolean[] element : array) {
			for (boolean element2 : element) {
				System.out.print(element2 + ",");
			}
			System.out.println("");
		}
		System.out.print("]");
	}

	public static void printTreeNode(TreeNode o) {
		Integer[] tree = TreeArray.tree2array(o);
		print(tree);
	}

	public static List<Integer> str2intlist(String s) {
		List<Integer> list = new ArrayList<>();
		int[] array = str2array3(s);
		if (array == null || array.length == 0)
			return list;
		for (int num : array) {
			list.add(num);
		}
		return list;
	}

	public static List<String> str2liststr(String s) {
		List<String> list = new ArrayList<>();
		String[] array = str2array2(s);
		if (array == null || array.length == 0)
			return list;
		for (String num : array) {
			list.add(num.trim());
		}
		return list;
	}

	public static List<List<Integer>> str2intlist1(String string2) {
		int[][] array = str2array1(string2);
		List<List<Integer>> result = new ArrayList<>();
		if (array == null || array.length == 0)
			return result;
		List<Integer> list = null;
		for (int[] row : array) {
			list = new ArrayList<>();
			for (int num : row) {
				list.add(num);
			}
			result.add(list);
		}
		return result;
	}

	public static List<List<String>> str2intlist2(String string2) {
		String[][] array = str2array1str(string2);
		List<List<String>> result = new ArrayList<>();
		if (array == null || array.length == 0)
			return result;
		List<String> list = null;
		for (String[] row : array) {
			list = new ArrayList<>();
			for (String num : row) {
				list.add(num.replace("\"", ""));
			}
			result.add(list);
		}
		return result;
	}

	public static int[][] str2array1(String s) {
		if (s == null || s.length() == 2)
			return new int[][] {};
		s = s.substring(2, s.length() - 2);
		String[] arr1 = s.split("],\\[");
		String[] arr2 = arr1[0].split(",");
		int row = arr1.length;
		int col = 0;
		for (int i = 0; i < row; i++) {
			col = Math.max(col, arr1[i].split(",").length);
		}
		int[][] result = new int[row][col];
		for (int i = 0; i < row; i++) {
			arr2 = arr1[i].split(",");
			result[i] = new int[arr2.length];
			for (int j = 0; j < arr2.length; j++) {
				result[i][j] = Integer.valueOf(arr2[j]);
			}
		}
		return result;
	}

	public static String[][] str2array1str(String s) {
		if (s == null || s.length() == 2)
			return new String[][] {};
		s = s.substring(2, s.length() - 2);
		String[] arr1 = s.split("],\\[");
		String[] arr2 = arr1[0].split(",");
		int row = arr1.length;
		int col = 0;
		for (int i = 0; i < row; i++) {
			col = Math.max(col, arr1[i].split(",").length);
		}
		String[][] result = new String[row][col];
		for (int i = 0; i < row; i++) {
			arr2 = arr1[i].split(",");
			result[i] = new String[arr2.length];
			for (int j = 0; j < arr2.length; j++) {
				result[i][j] = String.valueOf(arr2[j]);
			}
		}
		return result;
	}

	public static String[] str2array2(String s) {
		s = s.substring(1, s.length() - 1).replace("\"", "");
		if (s.length() == 0)
			return null;
		String[] result = s.split(",");
		return result;
	}

	public static int[] str2array3(String s) {
		s = s.substring(1, s.length() - 1);
		String[] result = s.split(",");
		if (result.length == 1 && result[0].equals(""))
			return null;
		int[] array = new int[result.length];
		for (int i = 0; i < result.length; i++) {
			array[i] = Integer.valueOf(result[i].trim());
		}
		return array;
	}

	public static int[] str2array31(String s) {
		s = s.substring(1, s.length() - 1);
		String[] result = s.split(",");
		if (result.length == 1 && result[0].equals(""))
			return new int[] {};
		int[] array = new int[result.length];
		for (int i = 0; i < result.length; i++) {
			array[i] = Integer.valueOf(result[i]);
		}
		return array;
	}

	/**
	 * @param string
	 * @return
	 * @see leetcode.code200.Solution200
	 */
	public static char[][] str2array5(String s) {
		if (s == null || s.length() == 2)
			return new char[][] {};
		s = s.substring(2, s.length() - 2);
		String[] arr1 = s.split("],\\[");
		String[] arr2 = arr1[0].split(",");
		int row = arr1.length;
		int col = 0;
		for (int i = 0; i < row; i++) {
			col = Math.max(col, arr1[i].split(",").length);
		}
		char[][] result = new char[row][col];
		for (int i = 0; i < row; i++) {
			arr2 = arr1[i].split(",");
			result[i] = new char[arr2.length];
			for (int j = 0; j < arr2.length; j++) {
				result[i][j] = arr2[j].replace("\"", "").charAt(0);
			}
		}
		return result;
	}

	public static Integer[] str2array4(String s) {
		s = s.substring(1, s.length() - 1);
		if (s.length() == 0)
			return null;
		String[] result = s.split(",");
		Integer[] array = new Integer[result.length];
		for (int i = 0; i < result.length; i++) {
			array[i] = (result[i] == null || result[i].equals("null")) ? null : Integer.valueOf(result[i]);
		}
		return array;
	}

	public static Object[] str2array6(String s) {
		s = s.substring(1, s.length() - 1);
		String[] result = s.split(",");
		Object[] array = new Object[result.length];
		for (int i = 0; i < result.length; i++) {
			System.out.println(result[i]);
			array[i] = result[i];
		}
		return array;
	}

	/**
	 * @param e
	 * @param r
	 * @return
	 */
	public static boolean compare(Object e, Object r) {
		boolean b = false;
		if (e instanceof int[] && r instanceof int[]) {
			b = compareArray1((int[]) e, (int[]) r);
		}
		if (e instanceof Integer && r instanceof Integer) {
			b = (int) e == (int) r;
		}
		if (e instanceof Boolean && r instanceof Boolean) {
			b = (boolean) e == (boolean) r;
		}
		if (e instanceof ListNode && r instanceof ListNode) {
			b = compareListNode((ListNode) e, (ListNode) r);
		}
		if (e instanceof int[][] && r instanceof int[][]) {
			b = compareArray2((int[][]) e, (int[][]) r);
		}
		if (e instanceof ArrayList<?> && r instanceof ArrayList<?>) {
			b = compareList((ArrayList<?>) e, (ArrayList<?>) r);
		}
		if (e instanceof List && r instanceof List) {
			b = compareList((List) e, (List) r);
		}
		if (e instanceof Node && r instanceof Node) {
			b = compareNode((Node) e, (Node) r);
		}
		if (e instanceof char[][] && r instanceof char[][]) {
			b = compareArray3((char[][]) e, (char[][]) r);
		}
		if (e instanceof String[][] && r instanceof String[][]) {
			b = compareArray4((String[][]) e, (String[][]) r);
		}
		if (e instanceof Double && r instanceof Double) {
			b = ((double) e == (double) r);
		}

		if (e instanceof String && r instanceof String) {
			b = e.toString().equals(r.toString());
		}
		if (e instanceof ListNode[] && r instanceof ListNode[]) {
			b = compareListNodeArray((ListNode[]) e, (ListNode[]) r);
		}
		System.out.println(" >>>>> 一致性 >>>> " + b);
		if (!b) {
			System.out.print(" 预期 > ");
			print(e);
			System.out.print(" 结果 > ");
			print(r);
		}
		return b;
	}

	private static boolean compareArray4(String[][] expect, String[][] result) {
		if (expect == null && result == null)
			return true;
		if ((expect == null && result != null) || (expect != null && result == null))
			return false;
		if (expect.length == result.length && expect.length == 0) {
			return true;
		}
		if (expect.length != result.length || expect[0].length != result[0].length) {
			return false;
		}
		for (int i = 0; i < expect.length; i++) {
			for (int j = 0; j < expect[0].length; j++) {
				if (expect[i][j].equals(result[i][j])) {
					return false;
				}
			}
		}
		return true;
	}

	private static boolean compareListNodeArray(ListNode[] expect, ListNode[] result) {
		if (expect == null && result == null)
			return true;
		if ((expect == null && result != null) || (expect != null && result == null))
			return false;
		if (expect.length != result.length)
			return false;
		for (int i = 0; i < expect.length; i++) {
			ListNode e = expect[i];
			ListNode r = result[i];
			while (e != null && r != null) {
				if (e.val != r.val)
					return false;
				e = e.next;
				r = r.next;
			}
		}
		return true;
	}

	private static boolean compareNode(Node expect, Node result) {
		if (expect == null && result == null) {
			return true;
		}
		if ((expect == null && result != null) || (expect != null && result == null)) {
			return false;
		}
		if (expect.val != result.val)
			return false;
		boolean bl = compareNode(expect.left, result.left);
		boolean br = compareNode(expect.right, result.right);
		boolean bn = compareNode(expect.next, result.next);
		if (bl && br && bn)
			return true;
		return false;
	}

	private static boolean compareList(List expect, List result) {
		if (expect == null && result == null)
			return true;
		if ((expect == null && result != null) || (expect != null && result == null))
			return false;
		if (expect.size() != result.size())
			return false;
		List temp = new ArrayList(result);
		for (int i = 0; i < expect.size(); i++) {
			Object o = expect.get(i);
//			if (o instanceof String) {
//				String.valueOf(o).equals(temp);
//			} else
			if (temp.contains(o.toString())) {
				temp.remove(o);
			} else
				return false;
		}
		if (temp.size() != 0)
			return false;
		return true;
	}

	private static boolean compareArray2(int[][] expect, int[][] result) {
		if (expect == null && result == null)
			return true;
		if ((expect == null && result != null) || (expect != null && result == null))
			return false;
		if (expect.length == result.length && expect.length == 0) {
			return true;
		}
		if (expect.length != result.length || expect[0].length != result[0].length) {
			return false;
		}
		for (int i = 0; i < expect.length; i++) {
			for (int j = 0; j < expect[0].length; j++) {
				if (expect[i][j] != result[i][j]) {
					return false;
				}
			}
		}
		return true;
	}

	public static boolean compareArray3(char[][] expect, char[][] result) {
		if (expect == null && result == null)
			return true;
		if ((expect == null && result != null) || (expect != null && result == null))
			return false;
		if (expect.length == result.length && expect.length == 0) {
			return true;
		}
		if (expect.length != result.length || expect[0].length != result[0].length) {
			return false;
		}
		for (int i = 0; i < expect.length; i++) {
			for (int j = 0; j < expect[0].length; j++) {
				if (expect[i][j] != result[i][j]) {
					return false;
				}
			}
		}
		return true;
	}

	private static boolean compareListNode(ListNode expect, ListNode result) {
		if (expect == null && result == null)
			return true;
		if ((expect == null && result != null) || (expect != null && result == null))
			return false;
		while (expect != null && result != null) {
			if (expect.val != result.val)
				return false;
			expect = expect.next;
			result = result.next;
		}
		if (expect != null || result != null)
			return false;
		return true;
	}

	public static boolean compareArray1(int[] expect, int[] result) {
		if (expect == null && result == null) {
			return true;
		}
		if ((expect == null && result != null) || (expect != null && result == null)) {
			return false;
		}
		if (expect.length != result.length) {
			return false;
		}
		for (int i = 0; i < expect.length; i++) {
			if (expect[i] != result[i]) {
				return false;
			}
		}
		return true;
	}

	public static Integer[] node2array(Node root) {
		if (root == null)
			return null;
		Queue<Node> result = new LinkedList<>();
		Queue<Node> queue = new LinkedList<>();
		queue.add(root);
		while (!queue.isEmpty()) {
			Node node = queue.poll();
			result.add(node);
			if (node == null) {
				continue;
			}
			if (node.left != null || node.right != null) {
				queue.add(node.left);
				queue.add(node.right);
			}
		}
		int len = result.size();
		Integer[] array = new Integer[len];
		for (int i = 0; i < len; i++) {
			Node node = result.poll();
			if (node == null) {
				array[i] = null;
			} else {
				array[i] = node.val;
			}
		}
		return array;
	}

}
